using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using SubSonic.DataProviders;
using SubSonic.Extensions;
using System.Linq.Expressions;
using SubSonic.Schema;
using System.Collections;
using SubSonic;
using SubSonic.Repository;
using System.ComponentModel;
using System.Data.Common;

namespace Entities
{
	/// <summary>
	/// A class which represents the curso table in the BemEstarEmprego Database.
	/// </summary>
	public partial class Tcurso : IActiveRecord
	{

		#region Built-in testing
		static TestRepository<Tcurso> _testRepo;



		static void SetTestRepo()
		{
			_testRepo = _testRepo ?? new TestRepository<Tcurso>(new Entities.BemEstarEmpregoDB());
		}
		public static void ResetTestRepo()
		{
			_testRepo = null;
			SetTestRepo();
		}
		public static void Setup(List<Tcurso> testlist)
		{
			SetTestRepo();
			foreach (var item in testlist)
			{
				_testRepo._items.Add(item);
			}
		}
		public static void Setup(Tcurso item)
		{
			SetTestRepo();
			_testRepo._items.Add(item);
		}
		public static void Setup(int testItems)
		{
			SetTestRepo();
			for (int i = 0; i < testItems; i++)
			{
				Tcurso item = new Tcurso();
				_testRepo._items.Add(item);
			}
		}

		public bool TestMode = false;


		#endregion

		IRepository<Tcurso> _repo;
		ITable tbl;
		bool _isNew;
		public bool IsNew()
		{
			return _isNew;
		}

		public void SetIsLoaded(bool isLoaded)
		{
			_isLoaded = isLoaded;
			if (isLoaded)
				OnLoaded();
		}

		public void SetIsNew(bool isNew)
		{
			_isNew = isNew;
		}
		bool _isLoaded;
		public bool IsLoaded()
		{
			return _isLoaded;
		}

		List<IColumn> _dirtyColumns;
		public bool IsDirty()
		{
			return _dirtyColumns.Count > 0;
		}

		public List<IColumn> GetDirtyColumns()
		{
			return _dirtyColumns;
		}

		Entities.BemEstarEmpregoDB _db;
		public Tcurso(string connectionString, string providerName)
		{

			_db = new Entities.BemEstarEmpregoDB(connectionString, providerName);
			Init();
		}
		void Init()
		{
			TestMode = this._db.DataProvider.ConnectionString.Equals("test", StringComparison.InvariantCultureIgnoreCase);
			_dirtyColumns = new List<IColumn>();
			if (TestMode)
			{
				Tcurso.SetTestRepo();
				_repo = _testRepo;
			}
			else
			{
				_repo = new SubSonicRepository<Tcurso>(_db);
			}
			tbl = _repo.GetTable();
			SetIsNew(true);
			OnCreated();

		}

		public Tcurso()
		{
			_db = new Entities.BemEstarEmpregoDB();
			Init();
		}


		partial void OnCreated();

		partial void OnLoaded();

		partial void OnSaved();

		partial void OnChanged();

		public IList<IColumn> Columns
		{
			get
			{
				return tbl.Columns;
			}
		}

		public Tcurso(Expression<Func<Tcurso, bool>> expression)
			: this()
		{

			SetIsLoaded(_repo.Load(this, expression));
		}



		internal static IRepository<Tcurso> GetRepo(string connectionString, string providerName)
		{
			Entities.BemEstarEmpregoDB db;
			if (String.IsNullOrEmpty(connectionString))
			{
				db = new Entities.BemEstarEmpregoDB();
			}
			else
			{
				db = new Entities.BemEstarEmpregoDB(connectionString, providerName);
			}
			IRepository<Tcurso> _repo;

			if (db.TestMode)
			{
				Tcurso.SetTestRepo();
				_repo = _testRepo;
			}
			else
			{
				_repo = new SubSonicRepository<Tcurso>(db);
			}
			return _repo;
		}

		internal static IRepository<Tcurso> GetRepo()
		{
			return GetRepo("", "");
		}

		public static Tcurso SingleOrDefault(Expression<Func<Tcurso, bool>> expression)
		{

			var repo = GetRepo();
			var results = repo.Find(expression);
			Tcurso single = null;
			if (results.Count() > 0)
			{
				single = results.ToList()[0];
				single.OnLoaded();
				single.SetIsLoaded(true);
				single.SetIsNew(false);
			}

			return single;
		}

		public static Tcurso SingleOrDefault(Expression<Func<Tcurso, bool>> expression, string connectionString, string providerName)
		{
			var repo = GetRepo(connectionString, providerName);
			var results = repo.Find(expression);
			Tcurso single = null;
			if (results.Count() > 0)
			{
				single = results.ToList()[0];
			}

			return single;


		}


		public static bool Exists(Expression<Func<Tcurso, bool>> expression, string connectionString, string providerName)
		{

			return All(connectionString, providerName).Any(expression);
		}
		public static bool Exists(Expression<Func<Tcurso, bool>> expression)
		{

			return All().Any(expression);
		}

		public static IList<Tcurso> Find(Expression<Func<Tcurso, bool>> expression)
		{

			var repo = GetRepo();
			return repo.Find(expression).ToList();
		}

		public static IList<Tcurso> Find(Expression<Func<Tcurso, bool>> expression, string connectionString, string providerName)
		{

			var repo = GetRepo(connectionString, providerName);
			return repo.Find(expression).ToList();

		}
		public static IQueryable<Tcurso> All(string connectionString, string providerName)
		{
			return GetRepo(connectionString, providerName).GetAll();
		}
		public static IQueryable<Tcurso> All()
		{
			return GetRepo().GetAll();
		}

		public static PagedList<Tcurso> GetPaged(string sortBy, int pageIndex, int pageSize, string connectionString, string providerName)
		{
			return GetRepo(connectionString, providerName).GetPaged(sortBy, pageIndex, pageSize);
		}

		public static PagedList<Tcurso> GetPaged(string sortBy, int pageIndex, int pageSize)
		{
			return GetRepo().GetPaged(sortBy, pageIndex, pageSize);
		}

		public static PagedList<Tcurso> GetPaged(int pageIndex, int pageSize, string connectionString, string providerName)
		{
			return GetRepo(connectionString, providerName).GetPaged(pageIndex, pageSize);

		}


		public static PagedList<Tcurso> GetPaged(int pageIndex, int pageSize)
		{
			return GetRepo().GetPaged(pageIndex, pageSize);

		}

		public string KeyName()
		{
			return "ID";
		}

		public object KeyValue()
		{
			return this.ID;
		}

		public void SetKeyValue(object value)
		{
			if (value != null && value != DBNull.Value)
			{
				var settable = value.ChangeTypeTo<long>();
				this.GetType().GetProperty(this.KeyName()).SetValue(this, settable, null);
			}
		}

		public override string ToString()
		{
			return this.DESCRICAO.ToString();
		}

		public override bool Equals(object obj)
		{
			if (obj.GetType() == typeof(Tcurso))
			{
				Tcurso compare = (Tcurso)obj;
				return compare.KeyValue() == this.KeyValue();
			}
			else
			{
				return base.Equals(obj);
			}
		}

		public string DescriptorValue()
		{
			return this.DESCRICAO.ToString();
		}

		public string DescriptorColumn()
		{
			return "DESCRICAO";
		}
		public static string GetKeyColumn()
		{
			return "ID";
		}
		public static string GetDescriptorColumn()
		{
			return "DESCRICAO";
		}

		#region ' Foreign Keys '
		#endregion


		long _ID;
		public long ID
		{
			get { return _ID; }
			set
			{
				if (_ID != value)
				{
					_ID = value;
					var col = tbl.Columns.SingleOrDefault(x => x.Name == "ID");
					if (col != null)
					{
						if (!_dirtyColumns.Any(x => x.Name == col.Name) && _isLoaded)
						{
							_dirtyColumns.Add(col);
						}
					}
					OnChanged();
				}
			}
		}

		string _DESCRICAO;
		public string DESCRICAO
		{
			get { return _DESCRICAO; }
			set
			{
				if (_DESCRICAO != value)
				{
					_DESCRICAO = value;
					var col = tbl.Columns.SingleOrDefault(x => x.Name == "DESCRICAO");
					if (col != null)
					{
						if (!_dirtyColumns.Any(x => x.Name == col.Name) && _isLoaded)
						{
							_dirtyColumns.Add(col);
						}
					}
					OnChanged();
				}
			}
		}

		string _TIPO;
		public string TIPO
		{
			get { return _TIPO; }
			set
			{
				if (_TIPO != value)
				{
					_TIPO = value;
					var col = tbl.Columns.SingleOrDefault(x => x.Name == "TIPO");
					if (col != null)
					{
						if (!_dirtyColumns.Any(x => x.Name == col.Name) && _isLoaded)
						{
							_dirtyColumns.Add(col);
						}
					}
					OnChanged();
				}
			}
		}



		public DbCommand GetUpdateCommand()
		{
			if (TestMode)
				return _db.DataProvider.CreateCommand();
			else
				return this.ToUpdateQuery(_db.Provider).GetCommand().ToDbCommand();

		}
		public DbCommand GetInsertCommand()
		{

			if (TestMode)
				return _db.DataProvider.CreateCommand();
			else
				return this.ToInsertQuery(_db.Provider).GetCommand().ToDbCommand();
		}

		public DbCommand GetDeleteCommand()
		{
			if (TestMode)
				return _db.DataProvider.CreateCommand();
			else
				return this.ToDeleteQuery(_db.Provider).GetCommand().ToDbCommand();
		}


		public void Update()
		{
			Update(_db.DataProvider);
		}

		public void Update(IDataProvider provider)
		{


			if (this._dirtyColumns.Count > 0)
			{
				_repo.Update(this, provider);
				_dirtyColumns.Clear();
			}
			OnSaved();
		}

		public void Add()
		{
			Add(_db.DataProvider);
		}



		public void Add(IDataProvider provider)
		{


			var key = KeyValue();
			if (key == null)
			{
				var newKey = _repo.Add(this, provider);
				this.SetKeyValue(newKey);
			}
			else
			{
				_repo.Add(this, provider);
			}
			SetIsNew(false);
			OnSaved();
		}



		public void Save()
		{
			Save(_db.DataProvider);
		}
		public void Save(IDataProvider provider)
		{


			if (_isNew)
			{
				Add(provider);

			}
			else
			{
				Update(provider);
			}

		}



		public void Delete(IDataProvider provider)
		{


			_repo.Delete(KeyValue());

		}


		public void Delete()
		{
			Delete(_db.DataProvider);
		}


		public static void Delete(Expression<Func<Tcurso, bool>> expression)
		{
			var repo = GetRepo();



			repo.DeleteMany(expression);

		}



		public void Load(IDataReader rdr)
		{
			Load(rdr, true);
		}
		public void Load(IDataReader rdr, bool closeReader)
		{
			if (rdr.Read())
			{

				try
				{
					rdr.Load(this);
					SetIsNew(false);
					SetIsLoaded(true);
				}
				catch
				{
					SetIsLoaded(false);
					throw;
				}
			}
			else
			{
				SetIsLoaded(false);
			}

			if (closeReader)
				rdr.Dispose();
		}


	}
}